package member.base.action;

import m.common.action.Action;
import m.common.model.FieldMeta;
import m.common.model.LinkTableMeta;
import m.common.model.Model;
import m.common.model.config.ModelConfig;
import m.common.model.type.FieldType;
import m.common.model.util.ModelQueryList;
import m.common.model.util.QueryCondition;
import m.common.model.util.QueryOrder;
import m.common.model.util.QueryPage;
import m.system.exception.MException;
import m.system.util.DateUtil;
import m.system.util.ObjectUtil;
import m.system.util.StringUtil;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

public abstract class BaseAction extends Action {
    private QueryPage page;
    private Map<String,String> params;

    /**
     * 获取params里的的值
     *  name
     *  不存在返回空字符串
     */
    public String getParamsValue(String name) {
        if(null!=this.getParams()&&null!=this.getParams().get(name)) {
            return StringUtil.noSpace(this.getParams().get(name));
        }
        return "";
    }
    /**
     * 构建查询 会根据page和params添加分页、查询条件和排序
     */
    public <T extends Model> ModelQueryList toQueryList(Class<T> clazz, String... fields) throws MException {
        List<QueryCondition> conditions=new ArrayList<>();
        List<QueryOrder> orders=new ArrayList<>();
        if(null!=params) {
            for (String key : params.keySet()) {
                String obj=params.get(key);
                if(key.contains("@")&&StringUtil.notSpace(obj)){
                    String[] arr=key.split("@");
                    String field=arr[0];
                    Object v=getValue(clazz,field,obj);
                    String oper=arr[1].toLowerCase().trim();
                    if((oper.equals("ge")||oper.equals("gt"))&&v instanceof Date){
                        v= DateUtil.getStartDay((Date)v);
                    }else if((oper.equals("le")||oper.equals("lt"))&&v instanceof Date){
                        v= DateUtil.getEndDay((Date)v);
                    }
                    if(oper.equals("eq")) conditions.add(QueryCondition.eq(field,v));
                    else if(oper.equals("ne")) conditions.add(QueryCondition.not(QueryCondition.eq(field,v)));
                    else if(oper.equals("like")) conditions.add(QueryCondition.like(field,v));
                    else if(oper.equals("isempty")) conditions.add(QueryCondition.isEmpty(field));
                    else if(oper.equals("notempty")) conditions.add(QueryCondition.notEmpty(field));
                    else if(oper.equals("isnull")) conditions.add(QueryCondition.isNull(field));
                    else if(oper.equals("notnull")) conditions.add(QueryCondition.notNull(field));
                    else if(oper.equals("gt")) conditions.add(QueryCondition.gt(field,v));
                    else if(oper.equals("ge")) conditions.add(QueryCondition.ge(field,v));//大于等于
                    else if(oper.equals("lt")) conditions.add(QueryCondition.lt(field,v));
                    else if(oper.equals("le")) conditions.add(QueryCondition.le(field,v));//小于等于
                    else if(oper.equals("in")) conditions.add(QueryCondition.in(field, (Object[]) v.toString().split(",")));
                }
                if(key.contains("#")&&StringUtil.notSpace(obj)){
                    String[] arr=key.split("#");
                    String field=arr[0];
                    String oper=arr[1].toLowerCase().trim();
                    if(oper.equals("desc")) orders.add(QueryOrder.desc(field));
                    else if(oper.isEmpty()||oper.equals("asc")) orders.add(QueryOrder.asc(field));
                }
            }
        }
        return ModelQueryList.instance(clazz,fields,page, QueryCondition.and(conditions.toArray(new QueryCondition[0])),orders.toArray(new QueryOrder[0]));
    }
    private <T extends Model> Object getValue(Class<T> clazz,String field,String value) throws MException {
        if(!field.contains(".")){
            if(field.equals("oid")){
                return value;
            }else{
                FieldMeta fm= ModelConfig.getFieldMetaMap(clazz).get(field);
                if(null!=fm){
                    if(fm.type()== FieldType.DATE) return ObjectUtil.convert(Date.class,value);
                    else if(fm.type()==FieldType.INT) return ObjectUtil.convert(Integer.class,value);
                    else if(fm.type()==FieldType.DOUBLE) return ObjectUtil.convert(Double.class,value);
                    else if(fm.type()==FieldType.LONG) return ObjectUtil.convert(Long.class,value);
                    return value;
                }else{
                    throw new MException(clazz+"."+field+"字段错误");
                }
            }
        }else {
            int index=field.indexOf(".");
            String cl=field.substring(0,index);
            String nf=field.substring(index+1);
            LinkTableMeta lt=ModelConfig.getLinkTableMetaMap(clazz).get(cl);
            if(null!=lt){
                return getValue(lt.table(),nf,value);
            }else{
                throw new MException(clazz+"."+field+"字段错误");
            }
        }
    }

    public QueryPage getPage() {
        return page;
    }

    public void setPage(QueryPage page) {
        this.page = page;
    }

    public Map<String, String> getParams() {
        return params;
    }

    public void setParams(Map<String, String> params) {
        this.params = params;
    }
}
